using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace Dragoon.BreakIt
{
    public class Ball : ICollisionSource
    {
        private Vector3 _origin;
        bool _rolling = false;
        double _rollStart;
        Vector3 _direction;   // unit vector
        bool _moving;
        private readonly Vector3 _initialOrigin;
        
        float _maxDistance;

        public int ArtWorkTextureSize = 1;
        public int ArtWorkShadowSize = 0;

        public float Speed = 0;    // units per second
        public readonly float Radius;

        internal Ball(Vector3 origin, float radius)
        {
            _initialOrigin = origin;
            Radius =  radius;
            Initialise();
        }


        public override string ToString()
        {
            return string.Format("Ball {0} - {1}", _origin, LocationAtEnd());
        }


        public Vector3 Velocity
        {
            get 
            { 
                return _direction; 
            }
        }

        public Vector3 LocationAt(GameTime time)
        {
            if (!_moving)
                return _origin;
            else if (!_rolling) // first call after heading change
            {
                _rollStart = time.TotalGameTime.TotalSeconds;
                _rolling = true;
                return _origin;
            }
            else
            {
                // v = d / t
                // d = v * t
                return LocationAt((float)(Speed *
                    (time.TotalGameTime.TotalSeconds
                    -_rollStart)));
            }
            
        }

        /// <summary>
        /// Returns the rectangle where the ball texture must be drawn
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public Rectangle DrawDestinationAt(GameTime time)
        {
            Vector3 ballPos = LocationAt(time);
            float diameter = (Radius * 2.0F);
            float shadowSize = diameter / (ArtWorkTextureSize - ArtWorkShadowSize);
            int destSize = (int)(diameter + shadowSize);
            return new Rectangle(
                (int)(ballPos.X - Radius),
                (int)(ballPos.Y - Radius),
                destSize, destSize);
        }

        public Vector3 LocationAt(float distance)
        {
            if (!_moving)
                return _origin;
            Vector3 r;
            if (distance > _maxDistance)
                r = (_direction * _maxDistance) + _origin;
            else
                r = (_direction * distance) + _origin;
            return r;
        }

        public Vector3 LocationAtEnd()
        {
            return LocationAt(_maxDistance);
        }

        internal void SetCourse(Ray heading, float maxDistance)
        {
            _origin = heading.Position;
            _direction = heading.Direction;            
            _maxDistance = maxDistance;
            _rolling = false;
            _moving = true;
        }

        internal void Initialise()
        {
            _origin = _initialOrigin;
            _maxDistance = 0F;
            _moving = false;
            _rolling = false;
        }

        internal Vector3 Origin
        {
            get
            {
                return _origin;
            }
        }
    }
}
